package com.ogj.newstar.service.impl;


import com.ogj.newstar.dao.TStationInfoDao;
import com.ogj.newstar.entity.TStationEntity;
import com.ogj.newstar.service.TStationInfoService;
import com.ogj.newstar.service.ex.EmptyArgumentException;
import com.ogj.newstar.service.ex.InsertException;
import com.ogj.newstar.util.PageUtils;
import com.ogj.newstar.util.Query;
import com.ogj.newstar.vo.OperationVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;


import com.ogj.newstar.dao.TOperationDao;
import com.ogj.newstar.entity.TOperationEntity;
import com.ogj.newstar.service.TOperationService;
import org.springframework.util.StringUtils;


//("tOperationService")
@Service("tOperationService")
public class TOperationServiceImpl extends ServiceImpl<TOperationDao, TOperationEntity> implements TOperationService {

    @Autowired
    TOperationDao operationDao;

    @Autowired
    TStationInfoService tStationInfoService;

    @Autowired
    TStationInfoDao tStationInfoDao;



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<TOperationEntity> page = this.page(
                new Query<TOperationEntity>().getPage(params),
                new QueryWrapper<TOperationEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void saveOperation(TOperationEntity operationEntity) {
        //进行验证
        //1、非空验证
        if(operationEntity==null||
                StringUtils.isEmpty(operationEntity.getUserIp())||
                StringUtils.isEmpty(operationEntity.getOptType())){
            throw new EmptyArgumentException("添加操作记录异常:操作记录为空");
        }
        if(operationEntity.getOptType().equals(1)){
            //拖拽操作
            if(operationEntity.getDragEndLat()==null||
            operationEntity.getDragEndLon()==null||
            operationEntity.getDragStartLat()==null||
            operationEntity.getDragStartLon()==null){
                throw new EmptyArgumentException("添加操作记录异常:拖拽记录为空");
            }
        }
        if (operationEntity.getOptType().equals(2)){
            if (operationEntity.getStationId()==null){
                throw new EmptyArgumentException("添加操作记录异常:点击记录为空");
            }
        }
        if (operationEntity.getOptType().equals(3)){
            if (operationEntity.getZoomStartLevel() == null||operationEntity.getZoomEndLevel()==null){
                throw new EmptyArgumentException("添加操作记录异常:缩放记录为空");
            }
        }

        //2、格式验证 TODO

        //3、业务逻辑验证 TODO

        //进行持久层方法调用
        Integer operation = operationDao.insertOperation(operationEntity);
        //对结果进行判断
        if(operation!=1){
            throw new InsertException("添加操作记录异常：添加失败");
        }
    }

    @Override
    public List<TOperationEntity> SelectOperationList() {
        List<TOperationEntity> operationList = operationDao.OperationList();
        //数据验证 TODO

        return operationList;
    }

    @Override
    public OperationVo getOperationViewObjectList(Integer topNumber) {
        int number = topNumber; //top数
        OperationVo vo = new OperationVo();
        //1、得到所有的用户操作数据
        List<TOperationEntity> operationList = operationDao.OperationList();
        //拿到所有的站点信息，这样就不用每次去sql获取数据了
        List<TStationEntity> stationList = tStationInfoService.getStationList();
        //2、根据不同的需求去过滤
        //2.1 地图访问量
        int size = operationList.size();
        vo.setOperationSum(size);
        //2.2 拖拽操作次数
        int count_drag = (int) operationList.stream().filter((item) -> item.getDragStartLon()!=null).count();
        vo.setOperationDragSum( count_drag);
        //2.3 缩放操作次数
        int count_adjust_level = (int) operationList.stream().filter((item)-> item.getZoomEndLevel()!=null).count();
        vo.setOperationLevelAdjustSum(count_adjust_level);
        //2.4 站点被点击的数量
        //使用concurrent hashmap
        //保证 线程安全
        //<站点name,站点总数>
        Map<Integer,Long> stationMapClickSum = new ConcurrentHashMap<>();
        stationMapClickSum = operationList
                .stream()
                .filter((item) -> item.getStationId() != null)
                .collect((Collectors.groupingBy(TOperationEntity::getStationId, Collectors.counting())));
        Map<String,Long> stationMapClickSum_name = new ConcurrentHashMap<>();
        stationMapClickSum.forEach((k,v)->{
            //根据id去查询
            List<TStationEntity> findStation = stationList.stream().filter(item -> item.getStationId().equals(k)).collect(Collectors.toList());
            if(findStation.size()!=0) {
                stationMapClickSum_name.put(findStation.get(0).getName(), v);
            }
        });
        vo.setOperationStationClick(stationMapClickSum_name);
        //2.5 得到所有的用户ip 不重复
        long UserIp_count = operationList.stream().filter((item)->item.getUserIp()!=null).map(TOperationEntity::getUserIp).distinct().count();
        //得到所有的站点id
        List<Integer> id_list=operationList.stream().filter(item->item.getStationId()!=null).map(TOperationEntity::getStationId).distinct().collect(Collectors.toList());
        vo.setUserIpSum(UserIp_count);
        //3、通过站点id排序去获取前五站点的名称信息
        List<Map.Entry<Integer, Long>> stationMapClickSumList = new CopyOnWriteArrayList<>(stationMapClickSum.entrySet());
        List<Map.Entry<Integer, Long>> sort_list = stationMapClickSumList
                                                .stream()
                                                .sorted((t1,t2)->{
                                                    return t2.getValue().compareTo(t1.getValue());
                                                }).collect(Collectors.toList());
        if(number>sort_list.size()){
            number = sort_list.size();
        }
        sort_list = sort_list.subList(0,number);
        sort_list.forEach(System.out::println);
        //使用juc中的组件  保证效率且线程安全
        List<String> station_Name_List = new CopyOnWriteArrayList<>();
        List<Long> station_SumNumber_List = new CopyOnWriteArrayList<>();
        sort_list.forEach((Station)->{
            //获取到它的id
            List<TStationEntity> findStation = stationList.stream().filter(item -> item.getStationId().equals(Station.getKey())).collect(Collectors.toList());
            station_Name_List.add(findStation.get(0).getName());
            station_SumNumber_List.add(Station.getValue());
        });
        vo.setTopFiveStationName(station_Name_List);
        vo.setTopFiveStationNumber(station_SumNumber_List);

        List<String> User_Ip_List = new CopyOnWriteArrayList<>();
        //获取前五位的 用户ip
        List<Map.Entry<String, Long>> userIpList =
                new CopyOnWriteArrayList<>(operationList
                        .stream()
                        .collect(Collectors.groupingBy(TOperationEntity::getUserIp, Collectors.counting())).entrySet());
        List<Map.Entry<String, Long>> collect = userIpList.stream().sorted((t1, t2) -> t2.getValue().compareTo(t1.getValue())).collect(Collectors.toList());
        if(number>collect.size()){
            number = collect.size();
        }
        collect = collect.subList(0,number);
        collect.forEach((item)->{
            User_Ip_List.add(item.getKey());
        });
        vo.setTopUserIp(User_Ip_List);
        //以操作类别分类，进行count计数
        Map<Integer, Long> OptTypeCount = operationList.stream().collect(Collectors.groupingBy(TOperationEntity::getOptType, Collectors.counting()));
        vo.setOperation_type_count(OptTypeCount);
        //对于每个站点，一类多少次，二类多少次， 三类多少次
//        List<Map.Entry<Integer, Long>> station_type_List = new CopyOnWriteArrayList<>(
//                operationList.stream().collect(Collectors.groupingBy(TOperationEntity::getOptType, Collectors.counting())).entrySet());
//        List<Map<String,List<Map.Entry<Integer,Long>>>> list=new CopyOnWriteArrayList<>();
//        id_list.forEach((item)->{
//            List<Map.Entry<Integer, Long>> onWriteArrayList = new CopyOnWriteArrayList<Map.Entry<Integer, Long>>(
//                     operationList.stream()
//                            .filter(u1 -> u1.getStationId()!=null&&item.equals(u1.getStationId()))
//                            .collect(Collectors.groupingBy(TOperationEntity::getOptType, Collectors.counting())).entrySet());
//            //去查name
//            Map<String, List<Map.Entry<Integer, Long>>> name_item=new ConcurrentHashMap<>();
//            if(onWriteArrayList.size()>0){
//                name_item.put(tStationInfoService.FindStationById(item).getName(),onWriteArrayList);
//                list.add(name_item);
//            }
//        });
//        vo.setStation_type_List(list);





        return vo;
    }


    @Override
    public TStationEntity selectByName(String name) {
        TStationEntity entity = tStationInfoDao.selectByName(name);
        return entity;
    }


}